home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d20
/
bsrc_250.arc
/
ZRECEIVE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-16
|
40KB
|
1,093 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ Bit-Bucket Software, Co. */
/* \ 10001101 / Writers and Distributors of */
/* \ 011110 / Freely Available<tm> Software. */
/* \ 1011 / */
/* ------ */
/* */
/* (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
/* */
/* */
/* Zmodem file reception module */
/* */
/* */
/* For complete details of the licensing restrictions, please refer */
/* to the License agreement, which is published in its entirety in */
/* the MAKEFILE and BT.C, and also contained in the file LICENSE.250. */
/* */
/* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
/* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
/* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
/* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
/* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
/* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
/* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
/* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
/* */
/* */
/* You can contact Bit Bucket Software Co. at any one of the following */
/* addresses: */
/* */
/* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
/* P.O. Box 460398 AlterNet 7:491/0 */
/* Aurora, CO 80046 BBS-Net 86:2030/1 */
/* Internet f491.n343.z1.fidonet.org */
/* */
/* Please feel free to contact us at any time to share your comments about */
/* our software and/or licensing policies. */
/* */
/* */
/* This module is based largely on a similar module in OPUS-CBCS V1.03b. */
/* The original work is (C) Copyright 1986, Wynn Wagner III. The original */
/* authors have graciously allowed us to use their code in this work. */
/* */
/*--------------------------------------------------------------------------*/
/* Include this file before any other includes or defines! */
#include "includes.h"
/*--------------------------------------------------------------------------*/
/* Local routines */
/*--------------------------------------------------------------------------*/
int RZ_ReceiveData (byte *, int);
int RZ_32ReceiveData (byte *, int);
int RZ_InitReceiver (void);
int RZ_ReceiveBatch (FILE *);
int RZ_ReceiveFile (FILE *);
int RZ_GetHeader (void);
int RZ_SaveToDisk (long *);
void RZ_AckBibi (void);
/*--------------------------------------------------------------------------*/
/* Private declarations */
/*--------------------------------------------------------------------------*/
static long DiskAvail;
static long filetime;
static char realname[64];
/*--------------------------------------------------------------------------*/
/* Private data */
/*--------------------------------------------------------------------------*/
/* Parameters for ZSINIT frame */
#define ZATTNLEN 32
static char Attn[ZATTNLEN + 1]; /* String rx sends to tx on
* err */
static FILE *Outfile; /* Handle of file being
* received */
static int Tryzhdrtype; /* Hdr type to send for Last
* rx close */
static char isBinary; /* Current file is binary
* mode */
static char EOFseen; /* indicates cpm eof (^Z)
* was received */
static char Zconv; /* ZMODEM file conversion
* request */
static int RxCount; /* Count of data bytes
* received */
static char Upload_path[PATHLEN]; /* Dest. path of file being
* received */
static long Filestart; /* File offset we started
* this xfer from */
/*--------------------------------------------------------------------------*/
/* GET ZMODEM */
/* Receive a batch of files. */
/* returns TRUE (1) for good xfer, FALSE (0) for bad */
/* can be called from f_upload or to get mail from a WaZOO Opus */
/*--------------------------------------------------------------------------*/
int get_Zmodem (char *rcvpath, FILE *xferinfo)
{
char namebuf[PATHLEN];
int i;
char *p;
char *HoldName;
long t;
#ifdef DEBUG
show_debug_name ("get_Zmodem");
#endif
filetime = 0;
IN_XON_ENABLE ();
/* Secbuf = NULL;*/
Outfile = NULL;
z_size = 0;
Rxtimeout = 100;
Tryzhdrtype = ZRINIT;
(void) strcpy (namebuf, rcvpath);
Filename = namebuf;
(void) strcpy (Upload_path, rcvpath);
p = Upload_path + strlen (Upload_path) - 1;
while (p >= Upload_path && *p != '\\')
--p;
*(++p) = '\0';
HoldName = HoldAreaNameMunge(&called_addr);
(void) sprintf (Abortlog_name, "%s%s.Z\0",
HoldName, Hex_Addr_Str (&remote_addr));
DiskAvail = zfree (Upload_path);
if (((i = RZ_InitReceiver ()) == ZCOMPL) ||
((i == ZFILE) && ((RZ_ReceiveBatch (xferinfo)) == OK)))
{
XON_DISABLE ();
XON_ENABLE (); /* Make sure xmitter is
* unstuck */
return 1;
}
CLEAR_OUTBOUND ();
XON_DISABLE (); /* Make sure xmitter is
* unstuck */
send_can (); /* transmit at least 10 cans */
t = timerset (200); /* wait no more than 2
* seconds */
while (!timeup (t) && !OUT_EMPTY () && CARRIER)
time_release (); /* Give up slice while
* waiting */
XON_ENABLE (); /* Turn XON/XOFF back on... */
/*
if (Secbuf)
free (Secbuf);
*/
if (Outfile)
(void) fclose (Outfile);
return 0;
} /* get_Zmodem */
/*--------------------------------------------------------------------------*/
/* RZ RECEIVE DATA */
/* Receive array buf of max length with ending ZDLE sequence */
/* and CRC. Returns the ending character or error code. */
/*--------------------------------------------------------------------------*/
int RZ_ReceiveData (register byte *buf, register int length)
{
register int c;
register word crc;
char *endpos;
int d;
#ifdef DEBUG
show_debug_name ("RZ_ReceiveData");
#endif
if (Rxframeind == ZBIN32)
return RZ_32ReceiveData (buf, length);
crc = RxCount = 0;
buf[0] = buf[1] = 0;
endpos = (char *)buf + length;
while ((char *)buf <= endpos)
{
if ((c = Z_GetZDL ()) & ~0xFF)
{
CRCfoo:
switch (c)
{
case GOTCRCE:
case GOTCRCG:
case GOTCRCQ:
case GOTCRCW:
/*-----------------------------------*/
/* C R C s */
/*-----------------------------------*/
crc = Z_UpdateCRC (((d = c) & 0xFF), crc);
if ((c = Z_GetZDL ()) & ~0xFF)
goto CRCfoo;
crc = Z_UpdateCRC (c, crc);
if ((c = Z_GetZDL ()) & ~0xFF)
goto CRCfoo;
crc = Z_UpdateCRC (c, crc);
if (crc & 0xFFFF)
{
z_message (MSG_TXT(M_CRC_MSG));
return ERROR;
}
RxCount = length - (int) (endpos - (char *) buf);
return d;
case GOTCAN:
/*-----------------------------------*/
/* Cancel */
/*-----------------------------------*/
z_log (MSG_TXT(M_CAN_MSG));
return ZCAN;
case TIMEOUT:
/*-----------------------------------*/
/* Timeout */
/*-----------------------------------*/
z_message (MSG_TXT(M_TIMEOUT));
return c;
case RCDO:
/*-----------------------------------*/
/* No carrier */
/*-----------------------------------*/
z_log (MSG_TXT(M_NO_CARRIER));
CLEAR_INBOUND ();
return c;
default:
/*-----------------------------------*/
/* Something bizarre */
/*-----------------------------------*/
z_message (MSG_TXT(M_DEBRIS));
CLEAR_INBOUND ();
return c;
} /* switch */
} /* if */
*buf++ = (unsigned char) c;
crc = Z_UpdateCRC (c, crc);
} /* while(1) */
z_message (MSG_TXT(M_LONG_PACKET));
return ERROR;
} /* RZ_ReceiveData */
/*--------------------------------------------------------------------------*/
/* RZ RECEIVE DATA with 32 bit CRC */
/* Receive array buf of max length with ending ZDLE sequence */
/* and CRC. Returns the ending character or error code. */
/*--------------------------------------------------------------------------*/
int RZ_32ReceiveData (register byte *buf, register int length)
{
register int c;
unsigned long crc;
char *endpos;
int d;
#ifdef DEBUG
show_debug_name ("RZ_32ReceiveData");
#endif
crc = 0xFFFFFFFF;
RxCount = 0;
buf[0] = buf[1] = 0;
endpos = (char *)buf + length;
while ((char *)buf <= endpos)
{
if ((c = Z_GetZDL ()) & ~0xFF)
{
CRCfoo:
switch (c)
{
case GOTCRCE:
case GOTCRCG:
case GOTCRCQ:
case GOTCRCW:
/*-----------------------------------*/
/* C R C s */
/*-----------------------------------*/
d = c;
c &= 0377;
crc = Z_32UpdateCRC (c, crc);
if ((c = Z_GetZDL ()) & ~0xFF)
goto CRCfoo;
crc = Z_32UpdateCRC (c, crc);
if ((c = Z_GetZDL ()) & ~0xFF)
goto CRCfoo;
crc = Z_32UpdateCRC (c, crc);
if ((c = Z_GetZDL ()) & ~0xFF)
goto CRCfoo;
crc = Z_32UpdateCRC (c, crc);
if ((c = Z_GetZDL ()) & ~0xFF)
goto CRCfoo;
crc = Z_32UpdateCRC (c, crc);
if (crc != 0xDEBB20E3)
{
z_message (MSG_TXT(M_CRC_MSG));
return ERROR;
}
RxCount = length - (int) (endpos - (char *)buf);
return d;
case GOTCAN:
/*-----------------------------------*/
/* Cancel */
/*-----------------------------------*/
z_log (MSG_TXT(M_CAN_MSG));
return ZCAN;
case TIMEOUT:
/*-----------------------------------*/
/* Timeout */
/*-----------------------------------*/
z_message (MSG_TXT(M_TIMEOUT));
return c;
case RCDO:
/*-----------------------------------*/
/* No carrier */
/*-----------------------------------*/
z_log (MSG_TXT(M_NO_CARRIER));
CLEAR_INBOUND ();
return c;
default:
/*-----------------------------------*/
/* Something bizarre */
/*-----------------------------------*/
z_message (MSG_TXT(M_DEBRIS));
CLEAR_INBOUND ();
return c;
} /* switch */
} /* if */
*buf++ = (unsigned char) c;
crc = Z_32UpdateCRC (c, crc);
} /* while(1) */
z_message (MSG_TXT(M_LONG_PACKET));
return ERROR;
} /* RZ_ReceiveData */
/*--------------------------------------------------------------------------*/
/* RZ INIT RECEIVER */
/* Initialize for Zmodem receive attempt, try to activate Zmodem sender */
/* Handles ZSINIT, ZFREECNT, and ZCOMMAND frames */
/* */
/* Return codes: */
/* ZFILE .... Zmodem filename received */
/* ZCOMPL ... transaction finished */
/* ERROR .... any other condition */
/*--------------------------------------------------------------------------*/
int RZ_InitReceiver ()
{
register int n;
int errors = 0;
char *sptr;
#ifdef DEBUG
show_debug_name ("RZ_InitReceiver");
#endif
for (n = 12; --n >= 0;)
{
/*--------------------------------------------------------------*/
/* Set buffer length (0=unlimited, don't wait). */
/* Also set capability flags */
/*--------------------------------------------------------------*/
Z_PutLongIntoHeader (0L);
Txhdr[ZF0] = CANFC32 | CANFDX | CANOVIO;
Z_SendHexHeader (Tryzhdrtype, (byte *)Txhdr);
if (Tryzhdrtype == ZSKIP)
Tryzhdrtype = ZRINIT;
AGAIN:
switch (Z_GetHeader ((byte *)Rxhdr))
{
case ZFILE:
Zconv = Rxhdr[ZF0];
Tryzhdrtype = ZRINIT;
if (RZ_ReceiveData (Secbuf, WAZOOMAX) == GOTCRCW)
return ZFILE;
Z_SendHexHeader (ZNAK, (byte *)Txhdr);
if (--n < 0)
{
sptr = "ZFILE";
goto Err;
}
goto AGAIN;
case ZSINIT:
if (RZ_ReceiveData ((byte *)Attn, ZATTNLEN) == GOTCRCW)
{
Z_PutLongIntoHeader (1L);
Z_SendHexHeader (ZACK, (byte *)Txhdr);
}
else Z_SendHexHeader (ZNAK, (byte *)Txhdr);
if (--n < 0)
{
sptr = "ZSINIT";
goto Err;
}
goto AGAIN;
case ZFREECNT:
Z_PutLongIntoHeader (DiskAvail);
Z_SendHexHeader (ZACK, (byte *)Txhdr);
goto AGAIN;
case ZCOMMAND:
/*-----------------------------------------*/
/* Paranoia is good for you... */
/* Ignore command from remote, but lie and */
/* say we did the command ok. */
/*-----------------------------------------*/
if (RZ_ReceiveData (Secbuf, WAZOOMAX) == GOTCRCW)
{
status_line (MSG_TXT(M_Z_IGNORING), Secbuf);
Z_PutLongIntoHeader (0L);
do
{
Z_SendHexHeader (ZCOMPL, (byte *)Txhdr);
}
while (++errors < 10 && Z_GetHeader ((byte *)Rxhdr) != ZFIN);
RZ_AckBibi ();
return ZCOMPL;
}
else Z_SendHexHeader (ZNAK, (byte *)Txhdr);
if (--n < 0)
{
sptr = "CMD";
goto Err;
}
goto AGAIN;
case ZCOMPL:
if (--n < 0)
{
sptr = "COMPL";
goto Err;
}
goto AGAIN;
case ZFIN:
RZ_AckBibi ();
return ZCOMPL;
case ZCAN:
sptr = MSG_TXT(M_CAN_MSG);
goto Err;
case RCDO:
sptr = &(MSG_TXT(M_NO_CARRIER)[1]);
CLEAR_INBOUND ();
goto Err;
} /* switch */
} /* for */
sptr = MSG_TXT(M_TIMEOUT);
Err:
(void) sprintf (e_input, MSG_TXT(M_Z_INITRECV), sptr);
z_log (e_input);
return ERROR;
} /* RZ_InitReceiver */
/*--------------------------------------------------------------------------*/
/* RZFILES */
/* Receive a batch of files using ZMODEM protocol */
/*--------------------------------------------------------------------------*/
int RZ_ReceiveBatch (FILE *xferinfo)
{
register int c;
char namebuf[PATHLEN];
#ifdef DEBUG
show_debug_name ("RZ_ReceiveBatch");
#endif
for (;;)
{
switch (c = RZ_ReceiveFile (xferinfo))
{
case ZEOF:
if (Resume_WaZOO)
{
remove_abort (Abortlog_name, Resume_name);
(void) strcpy (namebuf, Upload_path);
(void) strcat (namebuf, Resume_name);
unique_name (namebuf);
(void) rename (Filename, namebuf);
}
/* fallthrough */
case ZSKIP:
switch (RZ_InitReceiver ())
{
case ZCOMPL:
return OK;
default:
return ERROR;
case ZFILE:
break;
} /* switch */
break;
default:
(void) fclose (Outfile);
Outfile = NULL;
if (remote_capabilities)
{
if (!Resume_WaZOO)
{
add_abort (Abortlog_name, Resume_name, Filename, Upload_path, Resume_info);
}
}
else (void) unlink (Filename);
return c;
} /* switch */
} /* while */
} /* RZ_ReceiveBatch */
/*--------------------------------------------------------------------------*/
/* RZ RECEIVE FILE */
/* Receive one file; assumes file name frame is preloaded in Secbuf */
/*--------------------------------------------------------------------------*/
int RZ_ReceiveFile (FILE *xferinfo)
{
register int c;
int n;
long rxbytes;
char *sptr;
struct utimbuf utimes;
char j[50];
#ifdef DEBUG
show_debug_name ("RZ_ReceiveFile");
#endif
EOFseen = FALSE;
c = RZ_GetHeader ();
if (c == ERROR || c == ZSKIP)
return (Tryzhdrtype = ZSKIP);
n = 10;
rxbytes = Filestart;
for (;;)
{
Z_PutLongIntoHeader (rxbytes);
Z_SendHexHeader (ZRPOS, (byte *)Txhdr);
NxtHdr:
switch (c = Z_GetHeader ((byte *)Rxhdr))
{
case ZDATA:
/*-----------------------------------------*/
/* Data Packet */
/*-----------------------------------------*/
if (Rxpos != rxbytes)
{
if (--n < 0)
{
sptr = MSG_TXT(M_FUBAR_MSG);
goto Err;
}
(void) sprintf (j, "%s; %ld/%ld", MSG_TXT(M_BAD_POS), rxbytes, Rxpos);
z_message (j);
Z_PutString ((byte *)Attn);
continue;
}
MoreData:
switch (c = RZ_ReceiveData (Secbuf, WAZOOMAX))
{
case ZCAN:
sptr = MSG_TXT(M_CAN_MSG);
goto Err;
case RCDO:
sptr = &(MSG_TXT(M_NO_CARRIER)[1]);
CLEAR_INBOUND ();
goto Err;
case ERROR:
/*-----------------------*/
/* CRC error */
/*-----------------------*/
if (--n < 0)
{
sptr = MSG_TXT(M_FUBAR_MSG);
goto Err;
}
show_loc (rxbytes, n);
Z_PutString ((byte *)Attn);
continue;
case TIMEOUT:
if (--n < 0)
{
sptr = MSG_TXT(M_TIMEOUT);
goto Err;
}
show_loc (rxbytes, n);
continue;
case GOTCRCW:
/*---------------------*/
/* End of frame */
/*-----------------------*/
n = 10;
if (RZ_SaveToDisk (&rxbytes) == ERROR)
return ERROR;
Z_PutLongIntoHeader (rxbytes);
Z_SendHexHeader (ZACK, (byte *)Txhdr);
goto NxtHdr;
case GOTCRCQ:
/*---------------------*/
/* Zack expected */
/*-----------------------*/
n = 10;
if (RZ_SaveToDisk (&rxbytes) == ERROR)
return ERROR;
Z_PutLongIntoHeader (rxbytes);
Z_SendHexHeader (ZACK, (byte *)Txhdr);
goto MoreData;
case GOTCRCG:
/*---------------------*/
/* Non-stop */
/*-----------------------*/
n = 10;
if (RZ_SaveToDisk (&rxbytes) == ERROR)
return ERROR;
goto MoreData;
case GOTCRCE:
/*---------------------*/
/* Header to follow */
/*-----------------------*/
n = 10;
if (RZ_SaveToDisk (&rxbytes) == ERROR)
return ERROR;
goto NxtHdr;
} /* switch */
case ZNAK:
case TIMEOUT:
/*-----------------------------------------*/
/* Packet was probably garbled */
/*-----------------------------------------*/
if (--n < 0)
{
sptr = MSG_TXT(M_JUNK_BLOCK);
goto Err;
}
show_loc (rxbytes, n);
continue;
case ZFILE:
/*-----------------------------------------*/
/* Sender didn't see our ZRPOS yet */
/*-----------------------------------------*/
(void) RZ_ReceiveData (Secbuf, WAZOOMAX);
continue;
case ZEOF:
/*-----------------------------------------*/
/* End of the file */
/* Ignore EOF if it's at wrong place; force */
/* a timeout because the eof might have */
/* gone out before we sent our ZRPOS */
/*-----------------------------------------*/
if (locate_y && !(fullscreen && un_attended))
gotoxy (2, (byte) locate_y - 1);
if (Rxpos != rxbytes)
goto NxtHdr;
throughput (2, rxbytes - Filestart);
(void) fclose (Outfile);
status_line ("%s-Z%s %s", MSG_TXT(M_FILE_RECEIVED), Crc32 ? "/32" : "", realname);
update_files (0);
if (filetime)
{
utimes.UT_ACTIME = filetime;
utimes.modtime = filetime;
(void) utime (Filename, (UTIMBUF *)&utimes);
}
Outfile = NULL;
if (xferinfo != NULL)
{
(void) fprintf (xferinfo, "%s\n", Filename);
}
return c;
case ERROR:
/*-----------------------------------------*/
/* Too much garbage in header search error */
/*-----------------------------------------*/
if (--n < 0)
{
sptr = MSG_TXT(M_JUNK_BLOCK);
goto Err;
}
show_loc (rxbytes, n);
Z_PutString ((byte *)Attn);
continue;
case ZSKIP:
return c;
default:
sptr = IDUNNO_msg;
CLEAR_INBOUND ();
goto Err;
} /* switch */
} /* while */
Err:
(void) sprintf (e_input, MSG_TXT(M_Z_RZ), sptr);
z_log (e_input);
return ERROR;
} /* RZ_ReceiveFile */
/*--------------------------------------------------------------------------*/
/* RZ GET HEADER */
/* Process incoming file information header */
/*--------------------------------------------------------------------------*/
int RZ_GetHeader ()
{
register byte *p;
struct stat f;
int i;
char *ourname;
char *theirname;
long filesize;
char *fileinfo;
char j[80];
#ifdef DEBUG
show_debug_name ("RZ_GetHeader");
#endif
/*--------------------------------------------------------------------*/
/* Setup the transfer mode */
/*--------------------------------------------------------------------*/
isBinary = (char) ((!RXBINARY && Zconv == ZCNL) ? 0 : 1);
Resume_WaZOO = 0;
/*--------------------------------------------------------------------*/
/* Extract and verify filesize, if given. */
/* Reject file if not at least 10K free */
/*--------------------------------------------------------------------*/
filesize = 0L;
filetime = 0L;
fileinfo = (char *)Secbuf + 1 + strlen ((char *)Secbuf);
if (*fileinfo)
(void) sscanf (fileinfo, "%ld %lo", &filesize, &filetime);
if (filesize + 10240 > DiskAvail)
{
status_line (MSG_TXT(M_OUT_OF_DISK_SPACE));
return ERROR;
}
/*--------------------------------------------------------------------*/
/* Get and/or fix filename for uploaded file */
/*--------------------------------------------------------------------*/
p = (byte *)(Filename + strlen (Filename) - 1);/* Find end of upload path */
while ((char *)p >= Filename && *p != '\\')
p--;
ourname = (char *)++p;
p = Secbuf + strlen ((char *)Secbuf) - 1; /* Find transmitted simple
* filename */
while (p >= Secbuf && *p != '\\' && *p != '/' && *p != ':')
p--;
theirname = (char *)++p;
(void) strcpy (ourname, theirname); /* Start w/ our path & their
* name */
(void) strcpy (realname, Filename);
/*--------------------------------------------------------------------*/
/* Save info on WaZOO transfer in case of abort */
/*--------------------------------------------------------------------*/
if (remote_capabilities)
{
(void) strcpy (Resume_name, theirname);
(void) sprintf (Resume_info, "%ld %lo", filesize, filetime);
}
/*--------------------------------------------------------------------*/
/* Check if this is a failed WaZOO transfer which should be resumed */
/*--------------------------------------------------------------------*/
if (remote_capabilities && dexists (Abortlog_name))
{
Resume_WaZOO = (byte) check_failed (Abortlog_name, theirname, Resume_info, ourname);
}
/*--------------------------------------------------------------------*/
/* Open either the old or a new file, as appropriate */
/*--------------------------------------------------------------------*/
if (Resume_WaZOO)
{
if (dexists (Filename))
p = (byte *)"r+b";
else p = (byte *)write_binary;
}
else
{
(void) strcpy (ourname, theirname);
/*--------------------------------------------------------------------*/
/* If the file already exists: */
/* 1) And the new file has the same time and size, return ZSKIP */
/* 2) And OVERWRITE is turned on, delete the old copy */
/* 3) Else create a unique file name in which to store new data */
/*--------------------------------------------------------------------*/
if (dexists (Filename))
{ /* If file already exists... */
if ((Outfile = fopen (Filename, read_binary)) == NULL)
{
(void) got_error (MSG_TXT(M_OPEN_MSG), Filename);
return ERROR;
}
(void) fstat (fileno (Outfile), &f);
(void) fclose (Outfile);
if (filesize == f.st_size && filetime == f.st_mtime)
{
status_line (MSG_TXT(M_ALREADY_HAVE), Filename);
return ZSKIP;
}
i = strlen (Filename) - 1;
if ((!overwrite) || (is_arcmail (Filename, i)))
{
unique_name (Filename);
}
else
{
(void) unlink (Filename);
}
} /* if exist */
if (strcmp (ourname, theirname))
{
status_line (MSG_TXT(M_RENAME_MSG), ourname);
}
p = (byte *)write_binary;
}
if ((Outfile = fopen (Filename, (char *)p)) == NULL)
{
(void) got_error (MSG_TXT(M_OPEN_MSG), Filename);
return ERROR;
}
if (isatty (fileno (Outfile)))
{
errno = 1;
(void) got_error (MSG_TXT(M_DEVICE_MSG), Filename);
(void) fclose (Outfile);
return (ERROR);
}
Filestart = (Resume_WaZOO) ? filelength (fileno (Outfile)) : 0L;
if (Resume_WaZOO)
status_line (MSG_TXT(M_SYNCHRONIZING_OFFSET), Filestart);
(void) fseek (Outfile, Filestart, SEEK_SET);
if (remote_capabilities)
p = (byte *)check_netfile(theirname);
else p = NULL;
(void) sprintf (j, "%s %s; %s%ldb, %d min.",
(p != NULL) ? (char *)p : MSG_TXT(M_RECEIVING),
realname,
(isBinary) ? "" : "ASCII ",
filesize,
(int) ((filesize - Filestart) * 10 / cur_baud.rate_value + 53) / 54);
file_length = filesize;
if (un_attended && fullscreen)
{
clear_filetransfer ();
sb_move (file_hWnd, 1, 2);
FlLnModeSet( FILE_LN_2, 1 );
sb_puts( GetDlgItem( file_hWnd, FILE_LN_1 ), j );
elapse_time ();
i = (int) (filesize * 10 / cur_baud.rate_value + 53) / 54;
(void) sprintf(j, "%3d min", i);
sb_move (file_hWnd, 2, 69);
FlLnModeSet( FILE_LN_2, 1 );
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_DTTM ), j );
sb_show ();
}
else
{
set_xy (j);
set_xy (NULL);
locate_x += 2;
}
throughput (0, 0L);
return OK;
} /* RZ_GetHeader */
/*--------------------------------------------------------------------------*/
/* RZ SAVE TO DISK */
/* Writes the received file data to the output file. */
/* If in ASCII mode, stops writing at first ^Z, and converts all */
/* solo CR's or LF's to CR/LF pairs. */
/*--------------------------------------------------------------------------*/
int RZ_SaveToDisk (long *rxbytes)
{
static byte lastsent;
register byte *p;
register unsigned int count;
int i;
char j[100];
#ifdef DEBUG
show_debug_name ("RZ_SaveToDisk");
#endif
count = RxCount;
if (got_ESC ())
{
send_can (); /* Cancel file */
while ((i = Z_GetByte (20)) != TIMEOUT && i != RCDO) /* Wait for line to
* clear */
CLEAR_INBOUND ();
send_can (); /* and Cancel Batch */
z_log (MSG_TXT(M_KBD_MSG));
return ERROR;
}
if (count != z_size)
{
if (fullscreen && un_attended)
{
sb_move (file_hWnd, 2, 12);
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_SIZE ),
ultoa (((unsigned long) (z_size = count)), e_input, 10));
#ifndef MILQ
sb_puts (file_hWnd, " ");
#endif
elapse_time ();
sb_show ();
}
else
{
gotoxy (locate_x + 10, locate_y);
(void) cputs (ultoa (((unsigned long) (z_size = count)), e_input, 10));
(void) putch (' ');
}
}
if (isBinary)
{
if (fwrite (Secbuf, 1, count, Outfile) != count)
goto oops;
}
else
{
if (EOFseen)
return OK;
for (p = Secbuf; count > 0; count--)
{
if (*p == CPMEOF)
{
EOFseen = TRUE;
return OK;
}
if (*p == '\n')
{
if (lastsent != '\r' && putc ('\r', Outfile) == EOF)
goto oops;
}
else
{
if (lastsent == '\r' && putc ('\n', Outfile) == EOF)
goto oops;
}
if (putc ((lastsent = *p++), Outfile) == EOF)
goto oops;
}
}
*rxbytes += RxCount;
i = (int) ((file_length - *rxbytes)* 10 / cur_baud.rate_value + 53) / 54;
(void) sprintf (j, "%3d min", i);
if (fullscreen && un_attended)
{
elapse_time();
sb_move (file_hWnd, 2, 2);
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_TOTAL ),
ultoa (((unsigned long) (*rxbytes)), e_input, 10));
sb_move (file_hWnd, 2, 69);
sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_DTTM ), j );
elapse_time ();
sb_show ();
}
else
{
gotoxy (locate_x, locate_y);
(void) cputs (ultoa (((unsigned long) (*rxbytes)), e_input, 10));
gotoxy (locate_x + 20, locate_y);
(void) printf ("%s", j);
(void) putch (' ');
}
return OK;
oops:
(void) got_error (MSG_TXT(M_WRITE_MSG), Filename);
return ERROR;
} /* RZ_SaveToDisk */
/*--------------------------------------------------------------------------*/
/* RZ ACK BIBI */
/* Ack a ZFIN packet, let byegones be byegones */
/*--------------------------------------------------------------------------*/
void RZ_AckBibi ()
{
register int n;
#ifdef DEBUG
show_debug_name ("RZ_AckBiBi");
#endif
Z_PutLongIntoHeader (0L);
for (n = 4; --n;)
{
Z_SendHexHeader (ZFIN, (byte *)Txhdr);
switch (Z_GetByte (100))
{
case 'O':
(void) Z_GetByte (1); /* Discard 2nd 'O' */
case TIMEOUT:
case RCDO:
return;
} /* switch */
} /* for */
} /* RZ_AckBibi */